package com.xbongbong.parent.abstracts;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.help.log.InsertDataLogHelp;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.paas.help.FormDataValidateDataHelp;
import com.xbongbong.paas.help.ProSaveHelp;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.pojo.dto.FormDataAddDTO;
import com.xbongbong.paas.pojo.dto.SaasFormSaveDTO;
import com.xbongbong.paas.pojo.dto.ValidateDataDTO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.parent.interfaces.FormDataService;
import com.xbongbong.parent.pojo.AddValidateReturnPojo;
import com.xbongbong.pro.domain.entity.ReRollBackEntity;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.formdata.pojo.SaasNeedRedundantAttrPojo;
import com.xbongbong.pro.formdata.pojo.SaveFormExplainPojo;
import com.xbongbong.pro.formdata.pojo.vo.BeforeSaveVO;
import com.xbongbong.pro.formdata.pojo.vo.SaveVO;
import com.xbongbong.pro.permission.pojo.dto.VerifyAddPermissionDTO;
import com.xbongbong.pro.product.pojo.StockNotifyPojo;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ProductConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.enums.OperateModuleTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ProductEnum;
import com.xbongbong.saas.enums.business.QuotationEnum;
import com.xbongbong.saas.help.AnalyticalHelp;
import com.xbongbong.saas.service.toolbox.help.PackageStatusHelp;
import com.xbongbong.saas.service.toolbox.help.SaasSaveHelper;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.sys.help.ProPermissionHelp;
import com.xbongbong.sys.help.SysUserHelp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 *
 * @author 魏荣杰
 * @date 2020/12/30 10:22
 * @since
 * @version
 */
@Component
public abstract class AbstractFormDataService extends AbstractParentAddFormDataService<PaasFormEntityExt, PaasFormDataEntity> implements FormDataService<PaasFormEntityExt, PaasFormDataEntity> {

    private static final Logger LOG = LoggerFactory.getLogger(AbstractFormDataService.class);

    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private PackageStatusHelp packageStatusHelp;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private FormDataValidateDataHelp formDataValidateDataHelp;
    @Resource
    private AnalyticalHelp analyticalHelp;
    @Resource
    private SaasSaveHelper saasSaveHelper;
    @Resource
    private SysUserHelp sysUserHelp;
    @Resource
    protected CommonHelp commonHelp;
    @Resource
    private InsertDataLogHelp insertDataLogHelp;
//    @Resource
//    private RichTextService richTextService;
//
//    /**
//     * 保存富文本
//     *
//     * @param formDataAddDTO
//     * @param paasFormDataEntity
//     * @param richTextData 富文本数据
//     * @throws XbbException
//     */
//    protected void saveRichText(FormDataAddDTO formDataAddDTO, PaasFormDataEntity paasFormDataEntity,Object richTextData) throws XbbException{
//        richTextService.saveFormRichText(formDataAddDTO, paasFormDataEntity, richTextData);
//    }
//
//    /**
//     * 移除富文本
//     *
//     * @param data Json数据
//     * @return 富文本数据
//     * @throws XbbException
//     */
//    protected Object removeRichText(JSONObject data) throws XbbException{
//        return FormDataUtil.removeRichText(data);
//    }

    @Override
    public BeforeSaveVO beforeSave(FormDataAddDTO formDataSaveDTO) throws XbbException {
        BeforeSaveVO beforeSaveVO = new BeforeSaveVO();

        return beforeSaveVO;
    }

    @Override
    public PaasFormEntityExt getFormEntity(FormDataAddDTO formDataAddDTO) throws XbbException {
        PaasFormEntityExt paasFormEntityExt = paasFormModel.getByKey(formDataAddDTO.getFormId(), formDataAddDTO.getCorpid());

        paasFormModel.validateByPermission(paasFormEntityExt, formDataAddDTO.getLoginUser());
        return paasFormEntityExt;
    }

    @Override
    public AddValidateReturnPojo analyticalData(FormDataAddDTO formDataAddDTO, ValidateDataDTO validateDataDTO, Map<String, FieldAttrEntity> explainMap) throws XbbException {
        ProSaveHelp.analyticalData(validateDataDTO);
        // 校验必填字段
        formDataValidateDataHelp.validateData(validateDataDTO);
        // 校验各个业务的逻辑
        // TODO 不懂为啥标签要在saasSaveHelp.beforeSave里解析，为什么不放在ProSaveHelp.analyticalData
//        SaveFormatHelp.dealLabelData(validateDataDTO.getData(), explainMap);
        analyticalHelp.beforeSave(validateDataDTO);
        return new AddValidateReturnPojo();
    }




    @Override
    public BeforeSaveVO startWorkflowOrProcess(PaasFormDataEntity paasFormDataEntity, PaasFormEntityExt paasFormEntityExt, SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo, FormDataAddDTO formDataAddDTO, Map<String, FieldAttrEntity> explainMap, List<FieldAttrEntity> explainList) throws XbbException {
        BeforeSaveVO beforeSaveVO = new BeforeSaveVO();
        beforeSaveVO.setExplainMap(explainMap);
        beforeSaveVO.setPaasFormEntityExt(paasFormEntityExt);
        beforeSaveVO.setExplainList(explainList);
        beforeSaveVO.setSaasNeedRedundantAttrPojo(saasNeedRedundantAttrPojo);
        beforeSaveVO.setPaasFormDataEntity(paasFormDataEntity);

        //是否启用新工作流
        if (isEnableNewWorkflow(formDataAddDTO, beforeSaveVO, paasFormDataEntity)) {
            if (!formDataAddDTO.getIsSatisfyTrigger()) {
                // 无需走工作流
                beforeSaveVO.getPaasFormDataEntity().setFlowStatus(FlowStatusEnum.NOT_NEED_APPROVAL.getType());
            }
            return beforeSaveVO;
        }

        // 流程逻辑
        Integer noApprovalRequired = startProcess(formDataAddDTO, beforeSaveVO);


        beforeSaveVO.setNoApprovalRequired(noApprovalRequired);
        return beforeSaveVO;
    }

    @Override
    public BeforeSaveVO startWorkFlow(PaasFormDataEntity paasFormDataEntity, PaasFormEntityExt paasFormEntityExt, SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo, FormDataAddDTO formDataAddDTO, Map<String, FieldAttrEntity> explainMap, List<FieldAttrEntity> explainList) throws XbbException {
        BeforeSaveVO beforeSaveVO = new BeforeSaveVO(paasFormEntityExt, explainMap, paasFormDataEntity, explainList, saasNeedRedundantAttrPojo, 1);
        //是否启用新工作流
        if (isEnableNewWorkflow(formDataAddDTO, beforeSaveVO, paasFormDataEntity)) {
            if (!formDataAddDTO.getIsSatisfyTrigger()) {
                // 无需走工作流
                beforeSaveVO.getPaasFormDataEntity().setFlowStatus(FlowStatusEnum.NOT_NEED_APPROVAL.getType());
            }
        }
        return beforeSaveVO;
    }





    /**
     * 避免代码冗余，提起数据封装
     *
     * @param saasFormSaveDTO    入参
     * @param paasFormDataEntity 数据实体
     * @date 2019/1/28 14:34
     */
    public void packageSaasFormInsertSaveDTO(SaasFormSaveDTO saasFormSaveDTO, PaasFormDataEntity paasFormDataEntity) {
        saasFormSaveDTO.setIsNew(true);
        saasFormSaveDTO.setOldData(paasFormDataEntity.getData());
        saasFormSaveDTO.setNewData(paasFormDataEntity.getData());
        saasFormSaveDTO.setNewPaasFormDataEntity(paasFormDataEntity);
        saasFormSaveDTO.setOldPaasFormDataEntity(paasFormDataEntity);
    }

    @Override
    public void afterSaveRollBack(PaasFormDataEntity newPaasFormDataEntity, Long dataId, String corpid, Integer saasMark, Integer businessType, ReRollBackEntity reRollBackEntity) throws XbbException {
        try {
            // TODO 先在父类实现下，子类业务暂时未实现
        } catch (Exception e) {
            LOG.error("abstractFormDataServiceImpl.afterSaveRollBack 回滚失败：", e);
        }

    }



    protected UserVO getUserName(FormDataAddDTO formDataAddDTO, PaasFormDataEntity paasFormDataEntity) {
        return sysUserHelp.getUserName(formDataAddDTO.getCorpid(), formDataAddDTO.getUserId(), formDataAddDTO.getLoginUserName(), paasFormDataEntity.getFlowStatus(), paasFormDataEntity.getCreatorId());
    }



    /**
     * 设置特殊参数
     *
     * @param formDataSaveDTO
     * @param validateDataDTO
     * @throws
     * @author long.rao
     * @date 2019-10-09 10:36
     */
    protected void setSpecialParam(FormDataAddDTO formDataSaveDTO, ValidateDataDTO validateDataDTO) throws XbbException {
        if ( Objects.equals(formDataSaveDTO.getBusinessType(), XbbRefTypeEnum.QUOTATION.getCode()) ) {
            // 报价单组号不为1.0时，代表创建新版本(目前用于报价单新版本时不用校验同一组号的报价名称)
            JSONObject data = formDataSaveDTO.getDataList();
            String version = FastJsonHelper.getStringOrDefaultFromFormData(data, QuotationEnum.VERSION.getAttr(), StringConstant.DEFAULT_VERSION);
            if ( !Objects.equals(version, StringConstant.DEFAULT_VERSION) ) {
                validateDataDTO.setNewVersion(BasicConstant.ONE);
            }
        } else if (Objects.equals(formDataSaveDTO.getBusinessType(), XbbRefTypeEnum.PRODUCT.getCode())) {
            JSONObject data = formDataSaveDTO.getDataList();
            JSONObject specObj = data.getJSONObject(ProductEnum.SPECIFICATION.getAttr());
            if (Objects.isNull(specObj) || (Objects.equals(specObj.getInteger(ProductConstant.ADVANCED_MODE), 0) && StringUtil.isEmpty(specObj.getString(ProductConstant.SINGLE_SPEC)))) {
                if (Objects.equals(data.getInteger(ProductEnum.IS_NOTIFY.getAttr()), 1)) {
                    List<StockNotifyPojo> stockNotifyList = data.getJSONArray(ProductEnum.STOCK_NOTIFY.getAttr()).toJavaList(StockNotifyPojo.class);
                    for (StockNotifyPojo stockNotifyPojo : stockNotifyList) {
                        // 没有规格值得时候用空字符串
                        if (Objects.isNull(stockNotifyPojo.getArray_1())) {
                            JSONArray jsonArray = new JSONArray();
                            JSONObject jsonObject = new JSONObject();
                            jsonObject.put("", "");
                            jsonArray.add(jsonObject);
                            stockNotifyPojo.setArray_1(jsonArray);
                        }
                    }
                    data.put(ProductEnum.STOCK_NOTIFY.getAttr(), JSON.parseArray(JSON.toJSONString(stockNotifyList)));
                }
            }
        }
    }


    /**
     * 保存日志
     * @param formDataAddDTO
     * @param paasFormDataEntity
     * @param logName 日志名称
     * @param name
     * @param operateModuleTypeEnum
     * @param saveVO 插入接口返回的数据，
     * @param beforeSaveVO 备用参数
     * @return void
     * @author 吴峰
     * @date 2021/2/5 10:47
     * @throws XbbException
     */
    protected void saveLogger(FormDataAddDTO formDataAddDTO, PaasFormDataEntity paasFormDataEntity, String logName, String name, OperateModuleTypeEnum operateModuleTypeEnum, SaveVO saveVO,
                              BeforeSaveVO beforeSaveVO) {
        insertDataLogHelp.saveLogger(formDataAddDTO, paasFormDataEntity, logName, name, operateModuleTypeEnum, saveVO, beforeSaveVO);
    }


    @Override
    public void validatePermission(FormDataAddDTO formDataAddDTO) throws XbbException {

        if ( !Objects.equals(formDataAddDTO.getIsImport(), BasicConstant.ONE)) {
            String corpid = formDataAddDTO.getCorpid();
            Integer saasMark = formDataAddDTO.getSaasMark();
            Integer businessType = formDataAddDTO.getBusinessType();
            Long formId = formDataAddDTO.getFormId();
            if (!Objects.equals(1, formDataAddDTO.getIsBusinessRule())) {
                // 新建权限校验
                VerifyAddPermissionDTO verifyAddPermissionDTO = new VerifyAddPermissionDTO();
                BeanUtil.copyProperties(formDataAddDTO, verifyAddPermissionDTO);
                ProPermissionHelp.verifyAddPermission(verifyAddPermissionDTO);
            }
            // 非导入时判断数据量限制
            packageStatusHelp.validateData(corpid, saasMark, businessType, formId);
        }
    }






    /**
     * 获取字段解释（工单的解释在其自己的实现类）
     * @param formId
     * @param corpid
     * @return
     * @throws XbbException
     */
    @Override
    public SaveFormExplainPojo getExplainMap(Long formId, String corpid) throws XbbException{
        SaveFormExplainPojo saveFormExplainDTO = new SaveFormExplainPojo();

        PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByFormId(formId, corpid);
        if ( Objects.isNull(paasFormExplainEntity) ) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
        }
        saveFormExplainDTO.setExplainMap(ExplainUtil.getExplainMap(paasFormExplainEntity.getExplains(), null));
        saveFormExplainDTO.setExplainList(JSON.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class));
        return saveFormExplainDTO;
    }


}
